home *** CD-ROM | disk | FTP | other *** search
/ MacHack 1999 / MacHack 1999.toast / The Hacks / IrComm Remote / DVDRemote / DVDRemote.c < prev    next >
Encoding:
C/C++ Source or Header  |  1999-06-26  |  21.2 KB  |  934 lines  |  [TEXT/CWIE]

  1. /*
  2.     File:        MyCaptureAppShell.c
  3.     
  4.     Contains:    MyCaptureApp shell.
  5.  
  6.     Written by:    John Wang
  7.  
  8.     Copyright:    © 1994 by Apple Computer, Inc., all rights reserved.
  9.  
  10.     Change History (most recent first):
  11.  
  12.         <1>        04/04/94    JW        Created.
  13.  
  14.     To Do:
  15.         Wait till leave word rectangle
  16.         little L processor that Kat doesn't think should really be neccessary
  17.         
  18.     
  19. */
  20.  
  21.  
  22. #include    <Types.h>
  23. #include    <Memory.h>
  24. #include    <QuickDraw.h>
  25. #include    <Palettes.h>
  26. #include    <QDOffscreen.h>
  27. #include    <Errors.h>
  28. #include    <Fonts.h>
  29. #include    <Dialogs.h>
  30. #include    <Windows.h>
  31. #include    <Menus.h>
  32. #include    <Events.h>
  33. #include    <Devices.h>
  34. #include    <DiskInit.h>
  35. #include    <OSUtils.h>
  36. #include    <Resources.h>
  37. #include    <ToolUtils.h>
  38. #include    <AppleEvents.h>
  39. #include    <EPPC.h>
  40. #include    <Gestalt.h>
  41. #include    <Processes.h>
  42. #include    <Balloons.h>
  43. #include    <Aliases.h>
  44. #include    <MixedMode.h>
  45. #include    <Scrap.h>
  46. #include    <LowMem.h>
  47. #include    <Timer.h>
  48. #include    <Serial.h>
  49. #include    <Speech.h>
  50. #include    <TextUtils.h>
  51.  
  52. #include    <string.h>
  53.  
  54. #include "CommandStrings.h"
  55.  
  56.  
  57.  
  58. #include    "MyUtils.h"
  59. #include    "DVDRemote.h"
  60.  
  61. #define kMouseRegionWidth    120
  62. #define kMouseRegionHeight    50
  63.  
  64.  
  65. #define        rMonitor        1000
  66. #define        kSendButton        1
  67. #define        kStopButton        2
  68. #define        kQuitButton        3
  69. #define        kMsgBox            4
  70. #define        kSendSpinner    5
  71. #define        kRcvSpinner        7
  72. #define        kHoldFlag        9
  73. #define        kBreakButton    10
  74.  
  75. #define        rSerDataRsrc    128
  76. #define        rSpinnerIcon    1000
  77. #define        rHeldIcon        128
  78. #define        rNotHeldIcon    129
  79.  
  80. #define        rPortOpenALRT    256
  81. #define        kReset            2
  82.  
  83. #define        kCtlEnable        0
  84. #define        kCtlDisable        255
  85. #define        kSerBufSize        16384
  86. #define        kSerRdSize        64
  87. #define        kSerConfig        baud9600 + noParity + data8 + stop10
  88. #define        kBreakLength    666                // serial break length in milliseconds 
  89.  
  90. #define drvrName 0x12                // offset to driver name in 'DRVR' std. header 
  91.  
  92. #define dOpened  5
  93. #define dRAMBased  6
  94. #define drvrActive  7            // Device Manager DCtlFlag bits 
  95.                 
  96. #define kSerStatus  8
  97. #define kSerClrBrk  11            // Serial Driver csCodes 
  98. #define kSerSetBrk  12
  99. #define kSerHShakeDTR  14
  100. #define breakR0  128                // mask for break bit in SCC RR0 -- See TN #56 
  101. #define breakErr  8                    // mask for break bit in cumErrs -- System 7.0 
  102.  
  103. //#define kInputDriver "\p.AIn"
  104. //#define kOutputDriver "\p.AOut"
  105. #define kInputDriver "\p.IrIn"
  106. #define kOutputDriver "\p.IrOut"
  107.  
  108.  
  109. #define kDVDPlayerSignature    'ombz'
  110. #define kCDPlayerSignature        'aucd'
  111. //#define kTargetAppSignature    kDVDPlayerSignature
  112. #define kTargetAppSignature    kCDPlayerSignature
  113.  
  114.  
  115. //#define kDVDName "\pApple DVD Player"
  116. //#define kCDName "\pAppleCD Audio Player"
  117.  
  118. #define kUpArrowKey        0x7E1E
  119. #define kLeftArrowKey    0x7B1C
  120. #define kDownArrowKey    0x7D1F
  121. #define kRightArrowKey    0x7C1D
  122.  
  123. #define kSpaceBarKey    0x3120
  124. #define kPeriodKey        0x2F2E
  125. #define kEscapeKey        0x351B
  126. #define kEKey            0x0E45
  127. #define kMKey            0x2E4D
  128. #define k0Key            0x1D30
  129. #define k1Key            0x1231
  130. #define k2Key            0x1332
  131. #define k3Key            0x1433
  132. #define kPKey            0x2350
  133.  
  134. #ifdef powerc
  135. //QDGlobals        qd;
  136. #endif
  137.  
  138. Boolean            gDone;            //    Set to true if you want to Application to kindly quit.
  139.  
  140. WindowPtr        gWin = 0;
  141.  
  142. GWorldPtr        gRecognizeThis = 0;
  143. unsigned long gLastTicks = 0;
  144.  
  145.  
  146. Ptr            gpSerBuf, *ghSerBuf,            // serial receive buffer
  147.             gpOutputData, *ghOutputData,    // send buffer
  148.             gpBitBucket, *ghBitBucket;        // receive processing buffer
  149.  
  150. long        gOutputDataSize;
  151. IOParam        *gpSendPB, **ghSendPB;        // for PBWrite calls to send data
  152. short        gSysVersion,
  153.             gOutRefNum, gInRefNum,
  154. //            gSendCount = 0,
  155.             gBitBucketCount = 0;
  156. //char        *panicString = "Help! I'm stuffed! And here's a bunch of characters to prove it!\n\r";
  157. //TMTask        gPostEventTask;
  158.  
  159. ProcessSerialNumber    gTargetPSN;
  160.  
  161. long            gMessageToPost = 0;
  162. short            gMessageModifiers = 0;
  163.  
  164.  
  165. void    Initialize (void);
  166. short    SerInitialize (void);
  167. void    CleanUp (void);
  168. Boolean    OpenSERD (void);
  169. void    CloseSERD (void);
  170. //void    DoIOStuff (void);
  171. OSErr    SendData (void);
  172. void    CheckSerData (void);
  173. //void    CheckSerStatus (void);
  174. //pascal Boolean NullGrabber (DialogPtr, EventRecord *evt, short *itemHit);
  175. //pascal void    SendCompRout (void);
  176. //pascal void FlagBreakTimeout (void);
  177. void ProcessBitBucket(void);
  178. //void PrimeTMTask(void);
  179. void ProcessString(char* s);
  180. void FindTargetPSN(void);
  181. void SendEvents(void);
  182.  
  183. //#pragma parameter PostEventProc(__A0)
  184. //pascal void PostEventProc (void);
  185.  
  186.  
  187. //void DoStuffo(void);
  188.  
  189. /* ------------------------------------------------------------------------- */
  190.  
  191. void main()
  192. {
  193.     EventRecord     myEvent;
  194.     long            yieldTime = 10;
  195.     WindowPtr        foundWindow;
  196.     short            windowPart;
  197.     Boolean            isEvent;
  198.     GrafPtr            savePort;
  199.     GDHandle        saveGD;
  200.     OSErr            err=noErr;
  201.  
  202.     //    Initialize here.  Set the yield time too.
  203.     // bestTimeBase
  204. //    err = ProfilerInit(collectDetailed,microsecondsTimeBase,50,10);
  205.     Initialize();
  206.     FindTargetPSN();
  207.     
  208.     if(SerInitialize() != noErr) DebugStr("\pCan't init serial stuff");
  209.     
  210.     // open the Serial Driver 
  211.     if (! OpenSERD()) DebugStr("\pCan't open serial drvr");
  212.  
  213.     
  214.     //    Event loop.
  215.     for ( ; ; ) {
  216.  
  217.         //    Get the event.
  218.         isEvent = WaitNextEvent(everyEvent, &myEvent, yieldTime, nil);
  219.         
  220.         if(myEvent.what == keyDown)
  221.         {
  222.             myEvent.what = keyDown;
  223.         }
  224.         
  225.         CheckSerData();
  226.         ProcessBitBucket();
  227.         
  228.         SendEvents();
  229.         
  230.         //    If the event is unhandled by app specific event handling, then we proceed.
  231.         if ( isEvent ) {
  232.             switch ( myEvent.what ) {
  233.  
  234.                 case mouseDown:
  235.                     //    Get current port and device.
  236.                     GetPort(&savePort);
  237.                     saveGD = GetGDevice();
  238.                     
  239.                     //    Set the port and gdevice to the window if we own the window.
  240.                     //    We can then assume anytime the event occured in one of our windows,
  241.                     //       that the port and gdevice are set correctly.
  242.                     windowPart = FindWindow(myEvent.where, &foundWindow);
  243.                     SetPort(foundWindow);
  244.                     SetGDevice(GetMainDevice());
  245.                     
  246.                     //    Handle the different mouse down events.
  247.                     switch ( windowPart ) {
  248.                         case inSysWindow:
  249.                             SystemClick(&myEvent, foundWindow);
  250.                             break;
  251.                         case inMenuBar:
  252.                             DoCommand(MenuSelect(myEvent.where));
  253.                             break;
  254.                         case inContent:
  255.                             break;
  256.                         case inDrag:
  257.                             //    If dragging one of the application's windows, then handle it.
  258.                             //    However, if we are dragging a zoomed window, we
  259.                             //    must remember to save the new window location into the
  260.                             //    zoomed rect in the data handle.  Otherwise, the event
  261.                             //    manager will think that we are no longer zoomed.
  262.                             {
  263.                                 WStateData    *zoomData;
  264.                                 Rect        windowRect;
  265.                                 
  266.                                 //    Get window location before drag.
  267.                                 GetGlobalWindow(foundWindow, &windowRect);
  268.                                 
  269.                                 //    Drag window.
  270.                                 DragWindow (foundWindow, myEvent.where, &qd.screenBits.bounds);
  271. //                                MyDrag(foundWindow, myEvent.where);
  272.  
  273.                                 //    If the windowRect in global coordinates matches the zoom rect,
  274.                                 //    then assume that we are dragging the zoomed window.  update
  275.                                 //    zoom rect.
  276.                                 zoomData = (WStateData *) *(((CWindowPeek) foundWindow)->dataHandle);
  277.                                 if ( EqualRect(&(zoomData->stdState), &windowRect) ) {
  278.                                     GetGlobalWindow(foundWindow, &windowRect);
  279.                                     zoomData = (WStateData *) *(((CWindowPeek) foundWindow)->dataHandle);
  280.                                     zoomData->stdState = windowRect;
  281.                                 }
  282.                             }
  283.                             break;
  284.                         case inGrow:
  285.                             break;
  286.                         case inGoAway:
  287.                             //    Handle clicking on the go away.  If it is the clip window,
  288.                             //    then hide it.
  289.                             if ( TrackGoAway (foundWindow, myEvent.where) ) {
  290.                                 BringToFront(foundWindow);
  291. //                                MyClose();
  292.                                 DisposeWindow(foundWindow);
  293.                                 if(foundWindow == gWin) gWin = 0;
  294.                             }
  295.                             break;
  296.                         case inZoomIn:
  297.                         case inZoomOut:
  298.                             break;
  299.                         default:
  300.                             break;
  301.                     }
  302.                     
  303.                     //    Restore port and device.
  304.                     SetPort(savePort);
  305.                     SetGDevice(saveGD);
  306.                     
  307.                     break;
  308.                 case keyDown:
  309.                 case autoKey:
  310.                     if ( myEvent.modifiers & cmdKey ) {
  311.                         if ( myEvent.what == keyDown ) {
  312.                             DoCommand(MenuKey(myEvent.message & charCodeMask));
  313.                         }
  314.                     }
  315.                     break;
  316.                 case updateEvt:
  317.                     //    Handle update events for window and clip window.
  318.                     foundWindow = (WindowPtr) myEvent.message;
  319.                     GetPort(&savePort);
  320.                     saveGD = GetGDevice();
  321.                     SetPort(foundWindow);
  322.                     SetGDevice(GetMainDevice());
  323.                     BeginUpdate(foundWindow);
  324.                     EndUpdate(foundWindow);
  325.                     SetPort(savePort);
  326.                     SetGDevice(saveGD);
  327.                     break;
  328.                 case diskEvt:
  329.                     //    This handles a bad disk.  Otherwise the disk will not eject.
  330.                     if ( myEvent.message >> 16 ) {
  331.                         Point    tempPoint;
  332.                         tempPoint.v = 50; tempPoint.h = 50;
  333.                         DIBadMount(tempPoint, myEvent.message);
  334.                     }
  335.                     break;
  336.                 case activateEvt:
  337.                     break;
  338.                 case app4Evt:
  339.                     switch ( myEvent.message >> 24 ) {
  340.                         case suspendResumeMessage:
  341. //                            yieldTime = MyYieldTime(myEvent.message & 0x01);
  342.                             break;
  343.                         default:
  344.                             DebugStr("\pUnexpected suspend/resume message.");
  345.                     }
  346.                     break;
  347.                 default:
  348.                     break;
  349.             }
  350.         }
  351.     
  352.         //    If DoneFlag set, then quit.
  353.         if ( gDone ) {
  354. //            err = ProfilerDump((unsigned char *)"\pProfileInfo");
  355. //            ProfilerTerm();
  356.             CloseSERD();    // close the Serial Driver 
  357.             CleanUp();
  358.             
  359.             ExitToShell();
  360.         }
  361.     }
  362. }
  363.  
  364. /* ------------------------------------------------------------------------- */
  365.  
  366. void Initialize()
  367. {
  368. //    OSErr                err;
  369.     Handle                myMenu;
  370. //    Rect bounds;
  371.     
  372.     //    Initialize Managaer.
  373.     MaxApplZone();
  374.     MoreMasters(); MoreMasters();
  375.     MoreMasters(); MoreMasters();
  376.     MoreMasters(); MoreMasters();
  377.     MoreMasters(); MoreMasters();
  378.     InitGraf(&qd.thePort);
  379.     InitFonts();
  380.     FlushEvents(everyEvent, 0);
  381.     InitWindows();
  382.     InitDialogs(nil);
  383.     InitCursor();
  384.  
  385.     //    Set up menus.
  386.     myMenu = GetNewMBar(kMENUBAR);
  387.     SetMenuBar(myMenu);
  388.     DisposeHandle(myMenu);
  389.     AppendResMenu(GetMenuHandle(kMENU_APPLEID), 'DRVR');
  390.     DrawMenuBar();
  391.         
  392.     //    Setup other globals.
  393.     gDone = false;
  394.     
  395. /*    // Create window:
  396.     bounds.top = 50;
  397.     bounds.left = 50;
  398.     bounds.bottom = bounds.top + kMouseRegionHeight;
  399.     bounds.right = bounds.left + kMouseRegionWidth;
  400.     
  401.     gWin = NewCWindow(0, &bounds, "\pBits", true, documentProc, (WindowPtr)-1, true, 0);
  402.     SetPort(gWin);
  403.     
  404.     // Create gworld:
  405.     bounds.top = bounds.left = 0;
  406.     bounds.right = kMouseRegionWidth;
  407.     bounds.bottom = kMouseRegionHeight;
  408.     
  409.     err = NewGWorld(&gRecognizeThis, 16, &bounds, nil, nil, 0);    
  410. */
  411.     return;
  412. }
  413.  
  414. short SerInitialize (void)
  415. {
  416.     long    result;
  417.     OSErr    gestErr;
  418.     
  419.     gestErr = Gestalt(gestaltSystemVersion, &result);
  420.     gSysVersion = result;
  421.     
  422.     ghSendPB = (IOParam **) NewHandle( sizeof(IOParam));
  423.     if (ghSendPB != NULL) {
  424.         MoveHHi((Handle) ghSendPB);
  425.         HLock((Handle) ghSendPB);
  426.         gpSendPB = *ghSendPB;
  427.     }
  428.     else {
  429.         return MemError();
  430.     }
  431.  
  432.     ghSerBuf = NewHandle(kSerBufSize);
  433.     if (ghSerBuf != NULL) {
  434.         MoveHHi((Handle) ghSerBuf);
  435.         HLock((Handle) ghSerBuf);
  436.         gpSerBuf = *ghSerBuf;
  437.     }
  438.     else {
  439.         DisposeHandle((Handle) ghSendPB);
  440.         return MemError();
  441.     }
  442.     
  443.     ghBitBucket = NewHandle(kSerBufSize+1);
  444.     if (ghBitBucket != NULL) {
  445.         MoveHHi(ghBitBucket);
  446.         HLock(ghBitBucket);
  447.         gpBitBucket = *ghBitBucket;
  448.     }
  449.     else {
  450.         DisposeHandle((Handle) ghSendPB);
  451.         DisposeHandle((Handle) ghSerBuf);
  452.         return MemError();
  453.     }
  454.     
  455.     ghOutputData = Get1Resource('sDAT', rSerDataRsrc);
  456.     if (ghOutputData != NULL) {
  457.         MoveHHi(ghOutputData);
  458.         HLock(ghOutputData);
  459.         gpOutputData = *ghOutputData;
  460.         gOutputDataSize = GetResourceSizeOnDisk(ghOutputData);
  461.     }
  462.     else {
  463.         DisposeHandle((Handle) ghSendPB);
  464.         DisposeHandle((Handle) ghSerBuf);
  465.         DisposeHandle(ghBitBucket);
  466.         return ResError();
  467.     }
  468.         
  469.     return noErr;
  470. }
  471.  
  472.  
  473. void CleanUp (void)
  474. {
  475.  
  476.     DisposeHandle((Handle) ghSendPB);
  477.     DisposeHandle(ghSerBuf);
  478.     DisposeHandle(ghBitBucket);
  479. }
  480.  
  481.  
  482.  
  483. void DoCommand(long mResult)
  484. {
  485.     short             theMenu, theItem;
  486.     Str255            myStr;
  487.     GrafPtr            savePort;
  488.     GDHandle        saveGD;
  489.     
  490.     theItem = LoWord(mResult);
  491.     theMenu = HiWord(mResult);
  492.     
  493.     if ( theItem != 0 || theMenu != 0 ) {
  494.         switch ( theMenu ) {
  495.             case kMENU_APPLEID:
  496.                 if ( theItem == 1 ) {
  497.                     Alert(kALERT_ABOUT, nil);
  498.                 } else {
  499.                     GetMenuItemText(GetMenuHandle(kMENU_APPLEID), theItem, myStr);
  500.                     GetPort(&savePort);
  501.                     saveGD = GetGDevice();
  502.                     (void) OpenDeskAcc(myStr);
  503.                     SetPort(savePort);
  504.                     SetGDevice(saveGD);
  505.                 }
  506.                 break;
  507.     
  508.             case kMENU_FILEID:
  509.                 switch ( theItem ) {
  510.                     case kMENU_FILENEW:
  511. //                        MyNew();
  512.                         break;
  513.                     case kMENU_FILECLOSE:
  514. //                        MyClose();
  515.                         break;
  516.                     case kMENU_FILEQUIT:
  517.                         gDone = true;
  518.                         break;
  519.                     default:
  520.                         ReportFatal("\pError in handling file menu:", theItem);
  521.                 }
  522.                 break;
  523.         
  524.             default:
  525.                 ReportFatal("\pError in handling menu:", theMenu);
  526.         }
  527.     }
  528.     HiliteMenu(0);
  529. }
  530.  
  531.  
  532.  
  533.  
  534. Boolean OpenSERD (void)
  535. {
  536.     OSErr    openOutErr, openInErr;
  537.     OSErr    setBufErr, setCfgErr, setHskErr;
  538.     SerShk    hskFlags;
  539. //    long    finalTicks;
  540.     Boolean    takeOverPort = true;
  541. //    Boolean    openAOut, openAIn;
  542.     
  543. /*    openAOut = AssertDrvrOpen(kOutputDriver, &gOutRefNum) == noErr;
  544.     openAIn = AssertDrvrOpen(kInputDriver, &gInRefNum) == noErr;
  545.     if (openAOut || openAIn) {
  546.         if (takeOverPort = CautionAlert(rPortOpenALRT, nil) == kReset) {
  547.             if (openAIn) {
  548.                 KillIO(gInRefNum);
  549.                 CloseDriver(gInRefNum);
  550.             }
  551.             if (openAOut) {
  552.                 KillIO(gOutRefNum);
  553.                 CloseDriver(gOutRefNum);
  554.             }
  555.         }
  556.     }
  557.     
  558.     if (takeOverPort) {
  559. */
  560.         openOutErr = OpenDriver(kOutputDriver, &gOutRefNum);
  561.         openInErr = OpenDriver(kInputDriver, &gInRefNum);
  562.         
  563.         if (openOutErr == noErr && openInErr == noErr) {
  564.                     
  565.             // It's always good to first set a non-default input buffer, if desired. 
  566.             // There is no output buffering, so specify only the input driver.       
  567.             
  568.             setBufErr = SerSetBuf(gInRefNum, gpSerBuf, kSerBufSize);
  569.             
  570.             hskFlags.fXOn = false;
  571.             hskFlags.fCTS = true;
  572.             hskFlags.xOn = 0x11;
  573.             hskFlags.xOff = 0x13;
  574.             hskFlags.errs = 0;
  575.             
  576.             if (gSysVersion >= 0x0700) {
  577.                 hskFlags.evts = 0;                // I can use new means of break detection. 
  578.             }
  579.             else {
  580.                 hskFlags.evts = breakEvent;        // I need the driver to post break events. 
  581.             }
  582.             
  583.             hskFlags.fInX = false;
  584.             hskFlags.fDTR = true;
  585.             
  586.             // SerHShake() does not support full DTR/CTS hardware handshaking. You   
  587.             // accomplish the same thing and more with a Control call and csCode 14. 
  588.             // You only need to specify hskFlags once, to the output driver.         
  589.             
  590.             setHskErr = Control(gOutRefNum, kSerHShakeDTR, (Ptr) &hskFlags);
  591.  
  592.             // Now reset both input and output drivers with the same configuration.  
  593.             // Only a single call to the output driver is necessary to do this.      
  594.             // Differing concurrent input/output baud rates are not supported.       
  595.             
  596.             setCfgErr = SerReset(gOutRefNum, kSerConfig);
  597.             
  598.         }
  599.         else DebugStr("\pCan't open driver");
  600. //    }
  601.     
  602.     return takeOverPort;
  603. }
  604.  
  605.  
  606.  
  607. void CloseSERD (void)
  608. {
  609.     OSErr    killErr, closeOutErr, closeInErr;
  610.  
  611.     killErr = KillIO(gInRefNum);
  612.     closeInErr = CloseDriver(gInRefNum);
  613.  
  614.     killErr = KillIO(gOutRefNum);
  615.     closeOutErr = CloseDriver(gOutRefNum);
  616.  
  617. }
  618.  
  619.         
  620.  
  621.  
  622. void CheckSerData (void)
  623. {
  624.     OSErr    checkBufErr, serRdErr;
  625.     long    charCount;
  626.         
  627.     checkBufErr = SerGetBuf(gInRefNum, &charCount);
  628.     if (checkBufErr == noErr) {
  629.     
  630.         // The general strategy here is this: if number of available characters 
  631.         // meets a certain minimum threshold, then I read in everything in the  
  632.         // buffer. If I get delayed, I'll catch up quickly.                     
  633.  
  634. //        if (charCount != 0 && charCount >= reqBytes) {
  635.         if (charCount > 0) {
  636.             
  637.             serRdErr = FSRead(gInRefNum, &charCount, &gpBitBucket[gBitBucketCount]);
  638.             if (serRdErr == noErr) {
  639.                 gBitBucketCount += charCount;
  640.                 gpBitBucket[gBitBucketCount] = 0xFF; // append an 'unfinished string' terminator
  641.             }
  642.         }
  643.     }
  644. }
  645.  
  646. OSErr SendData (void)
  647. {
  648.     gpSendPB->ioCompletion = 0;//(ProcPtr)0;// SendCompRout;
  649.     gpSendPB->ioRefNum = gOutRefNum;
  650.     gpSendPB->ioBuffer = gpOutputData;
  651.     gpSendPB->ioReqCount = gOutputDataSize;
  652.     
  653. //    return PBWriteAsync((ParmBlkPtr) gpSendPB);            // asynchronous self-sustaining sends 
  654.     return PBWriteSync((ParmBlkPtr) gpSendPB);            // asynchronous self-sustaining sends 
  655.  
  656. }
  657.  
  658. /*
  659.     Searches the receive buffer, looking for 
  660.     completed (\r terminated) command strings to execute.
  661. */
  662. void ProcessBitBucket(void)
  663. {
  664.     char* s = gpBitBucket;
  665.     short i = 0;
  666.     Boolean foundString = false;
  667.     
  668.     while(foundString == false && i < gBitBucketCount)
  669.     {
  670.         if(s[i] == '\r')
  671.         {
  672.             foundString = true;
  673.             s[i] = 0; // null terminate the string
  674.         }
  675.         if(s[i] == 0xFF)
  676.         {
  677.             foundString = false;
  678.             break;
  679.         }
  680.         
  681.         i++;
  682.     }
  683.     
  684.     if(foundString == true) 
  685.     {
  686.         c2pstr(s);
  687.         SpeakString((unsigned char*)s);
  688.         p2cstr((unsigned char*)s);
  689.         
  690.         ProcessString(s);
  691.         
  692.         gBitBucketCount -= i;
  693.         BlockMove(&s[i], &s[0], gBitBucketCount);
  694.     }
  695.     
  696.     return;
  697. }
  698.  
  699.  
  700. /*
  701.     Given a command string, set the right 
  702.     event up to be posted to the CD/DVD player
  703. */
  704. void ProcessString(char* s)
  705. {
  706.  
  707.     if(strcmp(s, kPlayCmd) == 0 || 
  708.         strcmp(s, kPauseCmd) == 0)
  709.     {
  710. //        PostEvent(keyDown, ' ');
  711.         gMessageToPost = kSpaceBarKey;    // ' '
  712.         gMessageModifiers = 0;
  713.     }
  714.     else if(strcmp(s, kStopCmd) == 0)
  715.     {
  716.         gMessageToPost = kPeriodKey;    // cmd-.
  717.         gMessageModifiers = cmdKey;
  718.     }
  719.     else if(strcmp(s, kFastFwdCmd) == 0)
  720.     {
  721.         gMessageToPost = kRightArrowKey;    // cmd ->
  722.         gMessageModifiers = cmdKey;
  723.     }
  724.     else if(strcmp(s, kRewindCmd) == 0)
  725.     {
  726.         gMessageToPost = kLeftArrowKey;    // cmd <-
  727.         gMessageModifiers = cmdKey;
  728.     }
  729.     else if(strcmp(s, kNextCmd) == 0)
  730.     {
  731.         gMessageToPost = kRightArrowKey;    // -> arrow key
  732.         gMessageModifiers = 0;
  733.     }
  734.     else if(strcmp(s, kPrevCmd) == 0)
  735.     {
  736.         gMessageToPost = kLeftArrowKey;    // <- arrow key
  737.         gMessageModifiers = 0;
  738.     }
  739.     else if(strcmp(s, kEjectCmd) == 0)
  740.     {
  741.         gMessageToPost = kEKey;    // cmd-E
  742.         gMessageModifiers = cmdKey;
  743.     }
  744.     else if(strcmp(s, kVolUpCmd) == 0)
  745.     {
  746.         gMessageToPost = kUpArrowKey;    // cmd-up
  747.         gMessageModifiers = cmdKey;
  748.     }
  749.     else if(strcmp(s, kVolDownCmd) == 0)
  750.     {
  751.         gMessageToPost = kDownArrowKey;    // cmd-down
  752.         gMessageModifiers = cmdKey;
  753.     }
  754.     else if(strcmp(s, kMuteCmd) == 0)
  755.     {
  756.         gMessageToPost = kMKey;    // cmd-M
  757.         gMessageModifiers = cmdKey;
  758.     }
  759.     else if(strcmp(s, kDVDMenuCmd) == 0)
  760.     {
  761.         gMessageToPost = kEscapeKey;    // escape
  762.         gMessageModifiers = 0;
  763.     }
  764.     else if(strcmp(s, kSizeTinyCmd) == 0)
  765.     {
  766.         gMessageToPost = k0Key;    // cmd-0
  767.         gMessageModifiers = cmdKey;
  768.     }
  769.     else if(strcmp(s, kSizeHalfCmd) == 0)
  770.     {
  771.         gMessageToPost = k1Key;    // cmd-1
  772.         gMessageModifiers = cmdKey;
  773.     }
  774.     else if(strcmp(s, kSizeNormCmd) == 0)
  775.     {
  776.         gMessageToPost = k2Key;    // cmd-2
  777.         gMessageModifiers = cmdKey;
  778.     }
  779.     else if(strcmp(s, kSizeFullCmd) == 0)
  780.     {
  781.         gMessageToPost = k3Key;    // cmd-3
  782.         gMessageModifiers = cmdKey;
  783.     }
  784.     else if(strcmp(s, kPresentCmd) == 0)
  785.     {
  786.         gMessageToPost = kPKey;    // cmd-option-P
  787.         gMessageModifiers = cmdKey | optionKey;
  788.     }
  789.     
  790.     return;
  791. }
  792.  
  793. /*
  794.     Called repeatedly from our event loop, 
  795.     tries to send out an event if there is one pending.
  796. */
  797. void SendEvents(void)
  798. {
  799.     OSErr                        theErr;
  800.     ProcessSerialNumber    frontProcNum;
  801.     EvQElPtr                    theEventQElP;
  802.     Boolean                    result=false;
  803.     
  804.     if (gMessageToPost)
  805.     {
  806.         theErr = GetFrontProcess(&frontProcNum);
  807.         
  808.         if (theErr == noErr)
  809.         {
  810.             theErr = SameProcess(&frontProcNum, &gTargetPSN, &result);
  811.             if (theErr == noErr)
  812.             {
  813.                 if (result == true)
  814.                 {
  815.                     theErr = PPostEvent(keyDown, gMessageToPost /*q == 0x0C71*/, &theEventQElP);
  816.                     theEventQElP->evtQModifiers = gMessageModifiers;
  817.                     gMessageToPost = 0;
  818.                     gMessageModifiers = 0;
  819.                 } else
  820.                 {
  821.                     SetFrontProcess(&gTargetPSN);
  822.                 }
  823.             }
  824.         }
  825.     }
  826.     
  827.     return;
  828. }
  829.  
  830. /************************************************************
  831.  * Find PSN of target application
  832.  *************************************************************/ 
  833. void FindTargetPSN(void)
  834. {
  835.     OSErr                        theErr;
  836.     ProcessSerialNumber    thePSN;
  837.     ProcessInfoRec            theProcInfo;
  838.     unsigned char            theProcessName[32];
  839.  
  840.     thePSN.highLongOfPSN = 0;
  841.     thePSN.lowLongOfPSN = kNoProcess;
  842.  
  843.     theProcInfo.processInfoLength = sizeof(theProcInfo);
  844.     theProcInfo.processName = &theProcessName[0];
  845.     theProcInfo.processAppSpec = nil;
  846.     
  847.     do
  848.     {
  849.         theErr = GetNextProcess(&thePSN);
  850.         if (theErr == noErr)
  851.         {
  852.             theErr = GetProcessInformation(&thePSN, &theProcInfo);
  853.             if (theErr == noErr)
  854.             {
  855.     //            if ( EqualString(theProcInfo.processName, "\pTimeMgrTest", false, false) )
  856.                 if (theProcInfo.processType == 'APPL' && theProcInfo.processSignature == kTargetAppSignature)
  857.                 {
  858.                     gTargetPSN = thePSN;
  859.                     break;
  860.                 }
  861.             }
  862.         }
  863.     } while (theErr != procNotFound);
  864.     
  865.     if (theErr == procNotFound) {
  866.         DebugStr("\pCouldn't find target app");
  867.     }
  868.     return;    
  869. }
  870.  
  871. /************************************************************
  872.  * Initialize MyTimeMgrTask
  873.  *************************************************************/ 
  874. /*void InitMyTimeMgrTask(void)
  875. {
  876.     // Should call Gestalt to make sure the extended TimeMgr is present...
  877.  
  878.     gMyTimerUPP = NewTimerProc(MyTimeMgrTask);
  879.  
  880.     // Set up the fields in gMyTMTask
  881.     gMyTMTask.tmAddr = gMyTimerUPP;        // init as per IM
  882.     gMyTMTask.tmWakeUp = 0;                    // init as per IM
  883.     gMyTMTask.tmReserved = 0;                // init as per IM
  884.  
  885.     // Install MyTimeMgrTask into the queue
  886.     InsXTime((QElemPtr) &gMyTMTask);
  887.     
  888.     // Prime the task
  889.     PrimeTime((QElemPtr) &gMyTMTask, kDelay);
  890.  
  891.     return;
  892. }
  893. */
  894.  
  895.  
  896. /************************************************************
  897.  * MyTimeMgrTask
  898.  *************************************************************/ 
  899. /*void MyTimeMgrTask(TMTaskPtr tmTaskPtr)
  900. {
  901.     OSErr                        theErr;
  902.     ProcessSerialNumber    frontProcNum;
  903.     EvQElPtr                    theEventQElP;
  904.     Boolean                    result=false;
  905.     
  906.     if (gMessageToPost)
  907.     {
  908.         theErr = GetFrontProcess(&frontProcNum);
  909.     //    theErr = GetCurrentProcess(&frontProcNum);
  910.         if (theErr == noErr)
  911.         {
  912.             theErr = SameProcess(&frontProcNum, &gTargetPSN, &result);
  913.             if (theErr == noErr)
  914.             {
  915.                 if (result == true)
  916.                 {
  917.                     theErr = PPostEvent(keyDown, gMessageToPost, &theEventQElP);
  918.                     theEventQElP->evtQModifiers = gMessageModifiers;
  919.                     gMessageToPost = 0;
  920.                 } else
  921.                 {
  922.                     SetFrontProcess(&gTargetPSN);
  923.                 }
  924.             }
  925.         }
  926.     }
  927.  
  928. //    if (PostQuit != true)
  929.         PrimeTime((QElemPtr) tmTaskPtr, kDelay);
  930.  
  931.     return;
  932. }
  933. */
  934.